// SPDX-FileCopyrightText: Copyright 2025-2025 深圳市同心圆网络有限公司
// SPDX-License-Identifier: Apache-2.0

package resource_card_api_serv

import (
	"context"
	"time"

	"gitcode.com/lvupclub/lvup-api/dao"
	"gitcode.com/lvupclub/lvup-api/dao/resource_dao"
	"gitcode.com/lvupclub/lvup-api/dao/roadmap_dao"
	"gitcode.com/lvupclub/proto-gen-go.git/src/resource_api"
	"gitcode.com/lvupclub/proto-gen-go.git/src/resource_card_api"
	"gitcode.com/lvupclub/proto-gen-go.git/src/roadmap_data_type_api"
	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/types/known/anypb"
)

func (apiImpl *ResourceCardApiImpl) ListByRoadmap(ctx context.Context, req *resource_card_api.ListByRoadmapRequest) (*resource_card_api.ListByRoadmapResponse, error) {
	emptyList := []*resource_card_api.CardInfo{}

	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &resource_card_api.ListByRoadmapResponse{
			Code:     resource_card_api.ListByRoadmapResponse_CODE_WRONG_SESSION,
			ErrMsg:   "会话不存在",
			CardList: emptyList,
		}, nil
	}
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &resource_card_api.ListByRoadmapResponse{
			Code:     resource_card_api.ListByRoadmapResponse_CODE_NO_ROADMAP,
			ErrMsg:   "成长路线图不存在",
			CardList: emptyList,
		}, nil
	}
	allowAccess := apiImpl.checkAccessRoadmapNode(ctx, roadmapItem, sessItem, req.TargetMemberUserId)
	if !allowAccess {
		return &resource_card_api.ListByRoadmapResponse{
			Code:     resource_card_api.ListByRoadmapResponse_CODE_NO_PERMISSION,
			ErrMsg:   "没有权限",
			CardList: emptyList,
		}, nil
	}
	resourceId, valid := apiImpl.validNodeData(ctx, req.RoadmapId, req.NodeId)
	if !valid {
		return &resource_card_api.ListByRoadmapResponse{
			Code:     resource_card_api.ListByRoadmapResponse_CODE_NO_RESOURCE,
			ErrMsg:   "资料库不存在",
			CardList: emptyList,
		}, nil
	}

	cardIdList := []string{}
	stateItemList := []*resource_dao.CardStateItem{}
	if req.FilterByLearnLevel {
		stateItemList, err = resource_dao.CardStateDao.List(ctx, req.TargetMemberUserId, resourceId, true, req.LearnLevel)
		if err != nil {
			return nil, err
		}
		for _, stateItem := range stateItemList {
			cardIdList = append(cardIdList, stateItem.CardId)
		}
	} else {
		stateItemList, err = resource_dao.CardStateDao.List(ctx, req.TargetMemberUserId, resourceId, false, req.LearnLevel)
		if err != nil {
			return nil, err
		}
	}

	stateMap := map[string]*resource_dao.CardStateItem{}
	for _, stateItem := range stateItemList {
		stateMap[stateItem.CardId] = stateItem
	}

	count, err := resource_dao.CardInfoDao.Count(ctx, resourceId, false, "", req.FilterByLearnLevel, cardIdList)
	if err != nil {
		return nil, err
	}
	cardItemList, err := resource_dao.CardInfoDao.List(ctx, resourceId, false, "", req.FilterByLearnLevel, cardIdList, int64(req.Offset), int64(req.Limit))
	if err != nil {
		return nil, err
	}
	cardList, err := apiImpl.completeCardList(ctx, resourceId, cardItemList, req.WithContent)
	if err != nil {
		return nil, err
	}
	for _, card := range cardList {
		state, ok := stateMap[card.CardId]
		if ok {
			card.LearnLevel = state.LearnLevel
			card.LearnTime = state.LearnTime
		}
	}
	return &resource_card_api.ListByRoadmapResponse{
		Code:       resource_card_api.ListByRoadmapResponse_CODE_OK,
		TotalCount: count,
		CardList:   cardList,
	}, nil
}

func (apiImpl *ResourceCardApiImpl) checkAccessRoadmapNode(ctx context.Context, roadmapItem *roadmap_dao.RoadmapInfoDbItem, sessItem *dao.SessionDbItem, targetUserId string) bool {
	if roadmapItem.OwnerUserId == sessItem.UserId {
		if sessItem.UserId != targetUserId {
			exist, err := roadmap_dao.RoadmapMemberDao.Exist(ctx, roadmapItem.RoadmapId, targetUserId)
			if err != nil {
				return false
			}
			if !exist {
				return false
			}
		}
	} else {
		if sessItem.UserId != targetUserId {
			return false
		}
		exist, err := roadmap_dao.RoadmapMemberDao.Exist(ctx, roadmapItem.RoadmapId, targetUserId)
		if err != nil {
			return false
		}
		if !exist {
			return false
		}
	}
	return true
}

func (apiImpl *ResourceCardApiImpl) validNodeData(ctx context.Context, roadmapId, nodeId string) (string, bool) {
	nodeItem, err := roadmap_dao.NodeInfoDao.Get(ctx, roadmapId, nodeId)
	if err != nil {
		return "", false
	}

	nodeContent := &anypb.Any{}
	err = proto.Unmarshal(nodeItem.ContentData, nodeContent)
	if err != nil {
		return "", false
	}
	innerResourceData := &roadmap_data_type_api.InnerResourceData{}
	err = nodeContent.UnmarshalTo(innerResourceData)
	if err != nil {
		return "", false
	}
	return innerResourceData.ResourceId, innerResourceData.ResourceType == uint32(resource_api.RESOURCE_TYPE_RESOURCE_TYPE_CARD)
}

func (apiImpl *ResourceCardApiImpl) GetByRoadmap(ctx context.Context, req *resource_card_api.GetByRoadmapRequest) (*resource_card_api.GetByRoadmapResponse, error) {
	emptyInfo := &resource_card_api.CardInfo{
		BasicInfo: &resource_card_api.BasicCardInfo{},
		LinkList:  []*resource_card_api.ReleateCardLink{},
	}

	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &resource_card_api.GetByRoadmapResponse{
			Code:   resource_card_api.GetByRoadmapResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
			Card:   emptyInfo,
		}, nil
	}
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &resource_card_api.GetByRoadmapResponse{
			Code:   resource_card_api.GetByRoadmapResponse_CODE_NO_ROADMAP,
			ErrMsg: "成长路线图不存在",
			Card:   emptyInfo,
		}, nil
	}
	allowAccess := apiImpl.checkAccessRoadmapNode(ctx, roadmapItem, sessItem, req.TargetMemberUserId)
	if !allowAccess {
		return &resource_card_api.GetByRoadmapResponse{
			Code:   resource_card_api.GetByRoadmapResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
			Card:   emptyInfo,
		}, nil
	}
	resourceId, valid := apiImpl.validNodeData(ctx, req.RoadmapId, req.NodeId)
	if !valid {
		return &resource_card_api.GetByRoadmapResponse{
			Code:   resource_card_api.GetByRoadmapResponse_CODE_NO_RESOURCE,
			ErrMsg: "资料库不存在",
			Card:   emptyInfo,
		}, nil
	}
	cardItem, err := resource_dao.CardInfoDao.Get(ctx, resourceId, req.CardId)
	if err != nil {
		return &resource_card_api.GetByRoadmapResponse{
			Code:   resource_card_api.GetByRoadmapResponse_CODE_NO_CARD,
			ErrMsg: "知识卡片不存在",
			Card:   emptyInfo,
		}, nil
	}
	cardList, err := apiImpl.completeCardList(ctx, resourceId, []*resource_dao.CardInfoDbItem{cardItem}, true)
	if err != nil {
		return nil, err
	}
	if len(cardList) == 0 {
		return &resource_card_api.GetByRoadmapResponse{
			Code:   resource_card_api.GetByRoadmapResponse_CODE_NO_CARD,
			ErrMsg: "知识卡片不存在",
			Card:   emptyInfo,
		}, nil
	}
	stateItem, err := resource_dao.CardStateDao.Get(ctx, req.TargetMemberUserId, resourceId, req.CardId)
	if err == nil {
		cardList[0].LearnLevel = stateItem.LearnLevel
		cardList[0].LearnTime = stateItem.LearnTime
	}
	return &resource_card_api.GetByRoadmapResponse{
		Code: resource_card_api.GetByRoadmapResponse_CODE_OK,
		Card: cardList[0],
	}, nil
}

func (apiImpl *ResourceCardApiImpl) SetStateByRoadmap(ctx context.Context, req *resource_card_api.SetStateByRoadmapRequest) (*resource_card_api.SetStateByRoadmapResponse, error) {
	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &resource_card_api.SetStateByRoadmapResponse{
			Code:   resource_card_api.SetStateByRoadmapResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &resource_card_api.SetStateByRoadmapResponse{
			Code:   resource_card_api.SetStateByRoadmapResponse_CODE_NO_ROADMAP,
			ErrMsg: "成长路线图不存在",
		}, nil
	}
	if sessItem.UserId != roadmapItem.OwnerUserId {
		exist, err := roadmap_dao.RoadmapMemberDao.Exist(ctx, req.RoadmapId, sessItem.UserId)
		if err != nil {
			return nil, err
		}
		if !exist {
			return &resource_card_api.SetStateByRoadmapResponse{
				Code:   resource_card_api.SetStateByRoadmapResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}
	}
	resourceId, valid := apiImpl.validNodeData(ctx, req.RoadmapId, req.NodeId)
	if !valid {
		return &resource_card_api.SetStateByRoadmapResponse{
			Code:   resource_card_api.SetStateByRoadmapResponse_CODE_NO_RESOURCE,
			ErrMsg: "资料库不存在",
		}, nil
	}

	exist, err := resource_dao.CardInfoDao.Exist(ctx, resourceId, req.CardId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &resource_card_api.SetStateByRoadmapResponse{
			Code:   resource_card_api.SetStateByRoadmapResponse_CODE_NO_CARD,
			ErrMsg: "知识卡片不存在",
		}, nil
	}

	nowTime := time.Now().UnixMilli()

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx context.Context) (interface{}, error) {
		err = resource_dao.CardStateDao.Set(sessCtx, &resource_dao.CardStateItem{
			MemberUserId: sessItem.UserId,
			ResourceId:   resourceId,
			CardId:       req.CardId,
			LearnLevel:   req.LearnLevel,
			LearnTime:    nowTime,
		})
		if err != nil {
			return nil, err
		}
		return &resource_card_api.SetStateByRoadmapResponse{
			Code: resource_card_api.SetStateByRoadmapResponse_CODE_OK,
		}, nil
	})

	if err != nil {
		return nil, err
	}
	return ret.(*resource_card_api.SetStateByRoadmapResponse), nil
}

func (apiImpl *ResourceCardApiImpl) GetStateSummaryByRoadmap(ctx context.Context, req *resource_card_api.GetStateSummaryByRoadmapRequest) (*resource_card_api.GetStateSummaryByRoadmapResponse, error) {
	emptyInfo := &resource_card_api.CardStateSummaryInfo{}

	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &resource_card_api.GetStateSummaryByRoadmapResponse{
			Code:    resource_card_api.GetStateSummaryByRoadmapResponse_CODE_WRONG_SESSION,
			ErrMsg:  "会话不存在",
			Summary: emptyInfo,
		}, nil
	}
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &resource_card_api.GetStateSummaryByRoadmapResponse{
			Code:    resource_card_api.GetStateSummaryByRoadmapResponse_CODE_NO_ROADMAP,
			ErrMsg:  "成长路线图不存在",
			Summary: emptyInfo,
		}, nil
	}
	allowAccess := apiImpl.checkAccessRoadmapNode(ctx, roadmapItem, sessItem, req.TargetMemberUserId)
	if !allowAccess {
		return &resource_card_api.GetStateSummaryByRoadmapResponse{
			Code:    resource_card_api.GetStateSummaryByRoadmapResponse_CODE_NO_PERMISSION,
			ErrMsg:  "没有权限",
			Summary: emptyInfo,
		}, nil
	}
	resourceId, valid := apiImpl.validNodeData(ctx, req.RoadmapId, req.NodeId)
	if !valid {
		return &resource_card_api.GetStateSummaryByRoadmapResponse{
			Code:    resource_card_api.GetStateSummaryByRoadmapResponse_CODE_NO_RESOURCE,
			ErrMsg:  "资料库不存在",
			Summary: emptyInfo,
		}, nil
	}
	summary := &resource_card_api.CardStateSummaryInfo{}
	stateItemList, err := resource_dao.CardStateDao.List(ctx, req.TargetMemberUserId, resourceId, false, resource_card_api.LEARN_LEVEL_LEARN_LEVEL_NONE)
	if err != nil {
		return nil, err
	}
	for _, stateItem := range stateItemList {
		if stateItem.LearnLevel == resource_card_api.LEARN_LEVEL_LEARN_LEVEL_KNOW {
			summary.KnowCount += 1
		} else if stateItem.LearnLevel == resource_card_api.LEARN_LEVEL_LEARN_LEVEL_KNOW_WELL {
			summary.KnowWellCount += 1
		} else if stateItem.LearnLevel == resource_card_api.LEARN_LEVEL_LEARN_LEVEL_MASTER {
			summary.MasterCount += 1
		} else if stateItem.LearnLevel == resource_card_api.LEARN_LEVEL_LEARN_LEVEL_SKILLFUL {
			summary.SkillfulCount += 1
		}
	}

	return &resource_card_api.GetStateSummaryByRoadmapResponse{
		Code:    resource_card_api.GetStateSummaryByRoadmapResponse_CODE_OK,
		Summary: summary,
	}, nil
}
